Skip to content

fix(stop+validator): phase-aware stop docs + required_iter_root v2 (#198 + #199)#244

Merged
sriumcp merged 2 commits into
AI-native-Systems-Research:reflectivefrom
sriumcp:fix/stop-phase-and-iter-root-extensions
May 29, 2026
Merged

fix(stop+validator): phase-aware stop docs + required_iter_root v2 (#198 + #199)#244
sriumcp merged 2 commits into
AI-native-Systems-Research:reflectivefrom
sriumcp:fix/stop-phase-and-iter-root-extensions

Conversation

@sriumcp
Copy link
Copy Markdown
Collaborator

@sriumcp sriumcp commented May 29, 2026

Summary

Closes #198
Closes #199

Two related but independently-scoped fixes that close the post-#189 paper-burst friction tracker (#203) for the stop and validator surfaces.

Discovery context

While auditing #198 / #199 status I found that the behavioral halves of both were already shipped in earlier PRs — but neither issue had been closed because the closing PRs used Closes: **#N** (colon + bold) which doesn't match GitHub's auto-close regex. This PR delivers the remaining lagging deltas plus the explicit stretch-goal scope from #199's body, then closes both with proper auto-close keywords.

#198 — phase-aware nous stop documentation

The engine-side fix is in place: orchestrator/iteration.py:_enter_phase honours the STOP sentinel before every phase transition (DESIGN / HUMAN_DESIGN_GATE / EXECUTE_ANALYZE / HUMAN_FINDINGS_GATE), with comprehensive test coverage in TestEnterPhaseHonorsSentinel and TestRunIterationHaltsAtPhaseBoundary.

What lagged: two user-facing strings still said "iteration boundary":

  • orchestrator/cli.py:416 — schema-doc render's See-also section.
  • orchestrator/cli.py:879 — argparse help= for nous stop.

This PR updates both, adds an argparse description= so nous stop --help shows the full phase-aware explanation, and pins both against the legacy phrasing in TestStopDocumentationReflectsPhaseAwareness.

#199 v2 — required_iter_root

The v1 (iter_root_extensions) was already shipped — campaigns can declare additional iter-root files that don't trigger "unexpected file" rejection. This PR adds the explicit stretch goal from the issue body: campaigns can also declare files that MUST exist at iter root after EXECUTE_ANALYZE, with structured required iter-root file missing: X errors when they're absent.

# campaign.yaml
validation:
  required_iter_root:
    - "probe_report.md"
    - "manifest.json"
  iter_root_extensions:
    - "analysis_summary.json"

Semantics:

  • Required ⊆ allowed. A file in required_iter_root is also implicitly allowed at iter-root — no need to list it in both blocks.
  • validate_execution enforces presence. Sister to Better diagnostic when DESIGN exits without bundle.yaml/problem.md/handoff_snapshot.md #187's DesignIncompleteError and ExecuteAnalyzeIncompleteError analog of #187 for the EXECUTE phase #200's ExecuteAnalyzeIncompleteError: turn silent omissions into structured failures the operator can act on.
  • validate_design does NOT enforce presence. Required artifacts are typically EXECUTE-phase outputs (e.g. probe_report.md); checking at design time would surface false negatives. Design does merge required into the allowed-set so a campaign that writes the file during DESIGN doesn't get rejected by the unexpected-file check.
  • Backward compatible. Campaigns without a required_iter_root block behave exactly as before.

Files

  • orchestrator/cli.py — phase-boundary wording + new argparse description= for nous stop.
  • orchestrator/schemas/campaign.schema.yaml — new validation.required_iter_root field.
  • orchestrator/validate.py_campaign_required_iter_root helper, _check_required_iter_root, integration into validate_design (allowed-merge only) and validate_execution (allowed-merge + enforce-presence).
  • tests/test_nous_stop.pyTestStopDocumentationReflectsPhaseAwareness (2 tests).
  • tests/test_validate.pyTestRequiredIterRoot (7 tests).

Test plan

  • TDD red-green cycle verified for both fixes. 8 of 9 new tests fail before implementation; all 9 pass after.
  • nous stop should honor phase boundaries, not just iteration boundaries #198 polish: argparse nous stop --help and schema-doc render both contain "phase boundary" and don't contain "iteration boundary".
  • Validator's iter-root whitelist needs a per-campaign extension mechanism #199 v2: missing required → fail; present required → pass; required implicitly allowed at iter root; required-listed-alongside-other-errors; required+extensions combined; backward-compat with no required_iter_root block; jsonschema accepts the new field.
  • No live LLM calls. All tests use tmp_path fixtures and the existing block_live_llm_calls autouse fixture in conftest.py.
  • Full suite green. uv run pytest -q → 1245 passed, 1 skipped (+9 vs upstream/reflective baseline of 1236), 0 failures.

🤖 Generated with Claude Code

sriumcp added 2 commits May 29, 2026 10:10
Closes AI-native-Systems-Research#198
Closes AI-native-Systems-Research#199

## AI-native-Systems-Research#198 — phase-aware nous stop

The behavioral half of AI-native-Systems-Research#198 was already shipped (orchestrator/iteration.py
_enter_phase honours STOP sentinel before each phase transition; comprehensive
test coverage in TestEnterPhaseHonorsSentinel + TestRunIterationHaltsAtPhaseBoundary).

What lagged was user-facing documentation. Two surfaces still said
"iteration boundary":

  * orchestrator/cli.py:416 — schema-doc render's See-also section.
  * orchestrator/cli.py:879 — argparse help= for `nous stop`.

Both now describe phase-boundary semantics, with the argparse subparser
also gaining a `description=` so `nous stop --help` shows the full
explanation including which phase boundaries are honoured.

Tests in TestStopDocumentationReflectsPhaseAwareness pin both surfaces
against the legacy phrasing.

## AI-native-Systems-Research#199 v2 — required_iter_root

The v1 (iter_root_extensions) was already shipped. This PR adds the
stretch goal from the issue body: campaigns can declare files that
MUST exist at the iter root after EXECUTE_ANALYZE, with structured
"required iter-root file missing: X" errors when they're absent.

Wiring:

  * campaign.schema.yaml gains a validation.required_iter_root field
    (array of filenames).
  * orchestrator/validate.py grows _campaign_required_iter_root() and
    _check_required_iter_root() helpers.
  * validate_execution enforces presence; required ⊆ allowed (a required
    file is also implicitly allowed at iter-root, so campaigns don't
    have to list it in both blocks).
  * validate_design merges required into the allowed-set for the
    unexpected-file check (so campaigns that write the file during
    DESIGN don't get rejected), but does NOT enforce presence at design
    time — most required artifacts are EXECUTE-phase outputs.

Tests in TestRequiredIterRoot cover happy path, missing-required-fails,
implicit allowed-at-iter-root, schema acceptance, and backward-compat
(no-required-block keeps default behaviour).

Full suite: 1245 passed, 1 skipped (+9 vs upstream/reflective).
…ative-Systems-Research#199 v2)

Two test additions per pr-review-toolkit feedback on AI-native-Systems-Research#244:

1. test_required_file_at_design_time_is_allowed_not_required — pins
   the validate_design behaviour added in this PR: required ⊆ allowed
   merge lets a required file written during DESIGN pass the
   unexpected-file check, AND validate_design does NOT enforce
   required-presence (that's validate_execution's job because most
   required artifacts are EXECUTE-phase outputs). Without this test,
   a future refactor that inlines only the EXECUTE branch would
   silently regress DESIGN.

2. test_required_overlapping_known_root_file_still_enforced —
   a campaign declaring a globally-known file (e.g. findings.json)
   as required must still see "required iter-root file missing"
   when the file is absent, independent of the global whitelist
   semantics.

Suite: 1247 passed, 1 skipped (+11 vs upstream/reflective baseline).
@sriumcp sriumcp merged commit efc748f into AI-native-Systems-Research:reflective May 29, 2026
2 checks passed
@sriumcp sriumcp deleted the fix/stop-phase-and-iter-root-extensions branch May 29, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant